package com.fu.jdbc05;

import com.fu.jdbc05.handler.ResultSetHandler;
import com.fu.utils.DataSourceUtils;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 付大大
 * @description
 * @create 2021-01-31 16:14
 */
public class JDBCTemplate {
    private DataSource dataSource;
    private Connection connection;
    private PreparedStatement preparedStatement;
    private ResultSet resultSet;


    public JDBCTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public int update(String sql, Object... objects) {
        int result = 0;

        try {
            connection = dataSource.getConnection();

            preparedStatement = connection.prepareStatement(sql);

            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int parameterCount = parameterMetaData.getParameterCount();

            if (parameterCount != objects.length) {
                throw new RuntimeException("参数个数不匹配");
            }

            for (int i = 0; i < objects.length; i++) {
                preparedStatement.setObject(i + 1, objects[i]);
            }

            result = preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DataSourceUtils.close(connection, preparedStatement);
        }
        return result;
    }


    public <T> T queryForObject(String sql, ResultSetHandler<T> resultSetHandler, Object... objects) {
        T obj = null;

        try {
            connection = dataSource.getConnection();

            preparedStatement = connection.prepareStatement(sql);

            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int parameterCount = parameterMetaData.getParameterCount();

            if (parameterCount != objects.length) {
                throw new RuntimeException("参数个数不匹配");
            }

            for (int i = 0; i < objects.length; i++) {
                preparedStatement.setObject(i + 1, objects[i]);
            }

            resultSet = preparedStatement.executeQuery();

            obj = resultSetHandler.handler(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DataSourceUtils.close(connection, preparedStatement);
        }
        return obj;
    }


    public <T> List<T> queryForList(String sql, ResultSetHandler<T> resultSetHandler, Object... objects) {
        List<T> list = new ArrayList<>();
        try {
            connection = dataSource.getConnection();

            preparedStatement = connection.prepareStatement(sql);

            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int parameterCount = parameterMetaData.getParameterCount();

            if (parameterCount != objects.length) {
                throw new RuntimeException("参数个数不匹配");
            }

            for (int i = 0; i < objects.length; i++) {
                preparedStatement.setObject(i + 1, objects[i]);
            }

            resultSet = preparedStatement.executeQuery();

            list = resultSetHandler.handler(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DataSourceUtils.close(connection, preparedStatement);
        }
        return list;
    }


    public Long queryForScalar(String sql, ResultSetHandler<Long> resultSetHandler, Object... objects) {
        Long value = null;
        try {
            connection = dataSource.getConnection();

            preparedStatement = connection.prepareStatement(sql);

            ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();

            int parameterCount = parameterMetaData.getParameterCount();

            if (parameterCount != objects.length) {
                throw new RuntimeException("参数个数不匹配");
            }

            for (int i = 0; i < objects.length; i++) {
                preparedStatement.setObject(i + 1, objects[i]);
            }

            resultSet = preparedStatement.executeQuery();

            value = resultSetHandler.handler(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DataSourceUtils.close(connection, preparedStatement);
        }
        return value;
    }

}
